package com.bosch.in.rtp1.ept.manager.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.bosch.in.jfree.chart.BoxPlotChart;
import com.bosch.in.jfree.chart.LineChart;
import com.bosch.in.rtp1.ept.constant.CommonConstants;
import com.bosch.in.rtp1.ept.constant.FinishRecipeConstant;
import com.bosch.in.rtp1.ept.constant.ReleasedHoldParameter;
import com.bosch.in.rtp1.ept.manager.ChartManager;
import com.bosch.in.rtp1.ept.model.dto.BoxPlotFactor;
import com.bosch.in.rtp1.ept.model.dto.FshRcpChartFactors;
import com.bosch.in.rtp1.ept.model.dto.FshRcpChartValues;
import com.bosch.in.rtp1.ept.model.dto.HldDurByMonth;
import com.bosch.in.rtp1.ept.model.dto.LineChartPointFactor;
import com.bosch.in.rtp1.ept.model.dto.RelHldChartFactor;
import com.bosch.in.rtp1.ept.util.ChartUtility;

public class ChartManagerImpl  implements ChartManager{

	public ChartManagerImpl(){
	}
	
	@Override
	public List<String> getFshRcpsChart(List<FshRcpChartValues> chartValues, HttpServletRequest request,
			HttpServletResponse response, int year) throws IOException {
		List<String> chartList = new ArrayList<String>();
		int maxRange = this.getMaxRangeFshRcp(chartValues);
		String yAxisTitile = FinishRecipeConstant.Y_AXIS_TITLE;
		for (int i=0; i<chartValues.size(); ++i)
		{
			List<LineChartPointFactor> factors = ChartUtility.fromFshRcpChartFactorsToFshRcpFactor(chartValues.get(i).getFshRcpChartFactors(), year);
			String chartTitle = FinishRecipeConstant.PRIORITY_TITLE +" "+ chartValues.get(i).getPriority() + " - "+ FinishRecipeConstant.PROD_AREA_LIST[chartValues.get(i).getProdArea()-1];
			
			//create chart
			LineChart frChart = new LineChart(factors,chartTitle);
			
			//set clickable tooltip
			frChart.setClickableTooltip(true);
			
			frChart.setMaxRange(maxRange);
			frChart.setyAxisLabel(yAxisTitile);
			String newChart = frChart.createChart(request, response.getWriter(), FinishRecipeConstant.CHART_WIDTH, FinishRecipeConstant.CHART_HEIGHT, "");
			
			//add chart to return list
			chartList.add(newChart);
		}
		return chartList;
	}

	@Override
	public String getRelHldsChart(List<RelHldChartFactor> relHldChartFactors,
			HttpServletRequest request, HttpServletResponse response, int year)
			throws IOException {
		List<LineChartPointFactor> factors = ChartUtility.fromRelHldChartFactorsToFshRcpFactor(relHldChartFactors, year);
		LineChart frChart = new LineChart(factors, ReleasedHoldParameter.REL_HLD_CHART_TITLE);
		frChart.setyAxisLabel(ReleasedHoldParameter.Y_AXIS_LABEL_HLD_CHART);
		return  frChart.createChart(request, response.getWriter(), ReleasedHoldParameter.CHART_WIDTH, ReleasedHoldParameter.CHART_HEIGHT, "");
	}

	@Override
	public List<String> getHldDurByMonth(List<HldDurByMonth> hldByMonths,
			HttpServletRequest request, HttpServletResponse response, int year)
			throws IOException {
		List<String> chartFiles = new ArrayList<String>();
		int maxRange = this.getMaxRangeHldDur(hldByMonths);
		for (int i=0;i<hldByMonths.size(); ++i)
		{
			HldDurByMonth hByMonth = hldByMonths.get(i);
			String title = hByMonth.getMonth() + "-" + year + " , " + ReleasedHoldParameter.PRIO_TITLE + " " + hByMonth.getPriority();
			BoxPlotChart boxPlotChart = new BoxPlotChart(hByMonth.getBoxPlotFactors(),title);
			boxPlotChart.setMaxRange(maxRange);
			boxPlotChart.setyAxisTitle(ReleasedHoldParameter.Y_AXIS_LABEL_HLD_CHART);
			chartFiles.add(boxPlotChart.createChart(request, response.getWriter(), ReleasedHoldParameter.BOX_PLOT_WIDTH, ReleasedHoldParameter.BOX_PLOT_HEIGHT, ""));
		}
		return chartFiles;
	}
	
	@Override
	public String getHldActChart(List<BoxPlotFactor> boxPlotFactors, 
			HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		//SimpleDateFormat fm = new SimpleDateFormat(CommonConstants.FULL_DATE_FORMAT);
		
		//BoxPlotChart boxPlotChart = new BoxPlotChart(boxPlotFactors, CommonConstants.ACTIVE_HOLD_TITLE + QueryKeyWord.OPEN + fm.format(Calendar.getInstance().getTime()) + QueryKeyWord.CLOSE);
		BoxPlotChart boxPlotChart = new BoxPlotChart(boxPlotFactors, CommonConstants.ACTIVE_HOLD_TITLE);
		boxPlotChart.setyAxisTitle(ReleasedHoldParameter.Y_AXIS_LABEL_HLD_CHART);
		return boxPlotChart.createChart(request, response.getWriter(), ReleasedHoldParameter.CHART_WIDTH, ReleasedHoldParameter.CHART_HEIGHT, ""); 
	}
	
	/***********PRIVATE METHOD****************/
	
	/**
	 * Get max value of sigmaTop in the list of HldDurByMonth objects
	 * @param hldByMonths
	 * @return int
	 */
	private int getMaxRangeHldDur(List<HldDurByMonth> hldByMonths) {
		float maxRange = 0;
		for (int i=0;i<hldByMonths.size(); ++i)
		{
			HldDurByMonth hByMonth = hldByMonths.get(i);
			for (int j=0; j<hByMonth.getBoxPlotFactors().size();++j)
			{
				Float sigmaTop = hByMonth.getBoxPlotFactors().get(j).getSigmaTop();
				if (sigmaTop != null && maxRange<sigmaTop)
				{
					maxRange = sigmaTop;
				}
			}
		}
		return Math.round(maxRange+1);
	}
	
	/**
	 * Get max value of x-factors in the list of FshRcpChartValues objects
	 * @param hldByMonths
	 * @return int
	 */
	private int getMaxRangeFshRcp(List<FshRcpChartValues> chartValues) {
		float maxRange = 0;
		for (int i=0;i<chartValues.size(); ++i)
		{
			List<FshRcpChartFactors> cValues = chartValues.get(i).getFshRcpChartFactors();
			for (int j=0; j<cValues.size();++j)
			{
				FshRcpChartFactors lFactor = cValues.get(j);
				maxRange = lFactor.getFxPlan() == null ? maxRange : Math.max(maxRange, lFactor.getFxPlan());
				maxRange = lFactor.getFxRW() == null ? maxRange :Math.max(maxRange, lFactor.getFxRW());
				maxRange = lFactor.getFxRWH() == null ? maxRange :Math.max(maxRange, lFactor.getFxRWH());
				maxRange = lFactor.getxRW() == null ? maxRange :Math.max(maxRange, lFactor.getxRW());
				maxRange = lFactor.getxRWH() == null ? maxRange :Math.max(maxRange, lFactor.getxRWH());
				maxRange = lFactor.getxPlan() == null ? maxRange :Math.max(maxRange, lFactor.getxPlan());
			}
		}
		return Math.round(maxRange+1);
	}

	
}
